/*
 * User: user
 * Date: 12/02/2008
 * Time: 18:17:38
 */
package org.conann.container;

import com.google.common.base.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
import org.conann.CurrentAnnotation;
import org.conann.components.BeanImpl;
import org.conann.configuration.Configuration;

import javax.webbeans.Bean;
import java.lang.annotation.Annotation;
import static java.util.Arrays.asList;
import java.util.Set;

public class BeanResolver {

    private final Annotation[] defaultAnnotations = {new CurrentAnnotation()};
    private final Configuration configuration;
    private final BeansRegistry beansRegistry;

    public BeanResolver(Configuration configuration, BeansRegistry beansRegistry) {
        this.configuration = configuration;
        this.beansRegistry = beansRegistry;
    }

    public <T> Set<Bean<T>> resolveByType(Class<T> apiType, Annotation... bindingTypes) {
        checkNotNull(apiType);
        validateResolutionRequest(bindingTypes);
        bindingTypes = getDefaultIfEmpty(bindingTypes);

        Set<Bean<T>> matchingTypes = Sets.newHashSetWithExpectedSize(4);

        for (Bean<?> bean : beansRegistry.getConformingBeans(apiType)) {
            if (isMatching(bean, bindingTypes)) {
                matchingTypes.add((Bean<T>) bean);
            }
        }
        return matchingTypes;
    }

    private void validateResolutionRequest(Annotation[] bindingTypes) {

    }

    private Annotation[] getDefaultIfEmpty(Annotation... bindingTypes) {
        return bindingTypes.length == 0 ? defaultAnnotations : bindingTypes;
    }

    private boolean isMatching(final Bean<?> bean, Annotation... bindingTypes) {
        return Iterables.all(asList(bindingTypes), new Predicate<Annotation>() {
            public boolean apply(@Nullable Annotation bindingType) {
                return ((BeanImpl<?>) bean).matches(bindingType);
            }
        });
    }
}